﻿' ----------------------------------------------------------------------
'
' FileSystemEntity.vb
'
'   ... Classes
'
'   Provides the base class for both FileEntity and DirectoryEntity 
'   objects.
'
' ----------------------------------------------------------------------
' version:  1.0.0.1
' today:    02/09/06  11:26:00
' ident:    "@(#)/Dbfs/Domain/FileSystemEntity.vb 1.0 0.1 02/09/09 0 rjs"

Imports System.IO
Imports Dbfs.Security


Namespace Dbfs

    ''' <summary>
    ''' Provides the base class for both <see cref="FileEntity"/> and <see cref="DirectoryEntity"/> objects.
    ''' </summary>
    ''' <remarks>This is a container class for the information that comprises a <see cref="FileSystemInfo"/>.
    ''' It holds a reference to a shared copy of a <see cref="FileSystemItemSet"/> and a reference
    ''' to an updatable instance of a <see cref="FileSystemItem"/>.  Instances of this class are
    ''' created by and for the 'Info' classes and are passed as entities to the data mapper classes.
    ''' </remarks>
    <SerializableAttribute()> _
    Public MustInherit Class FileSystemEntity

        ''' <summary>
        ''' The access rights for this instance, i.e. for the current user.
        ''' </summary>
        ''' <remarks></remarks>
        Private _accessRights As System.Security.AccessControl.FileSystemRights

        ''' <summary>
        ''' A Dictionary of keyword-value pairs that represent additional
        ''' attributes for this object.
        ''' </summary>
        ''' <remarks></remarks>
        Private _extendedAttributes As NodeAttributes
        ' TODO: this needs to be changed to StringDictionary

        ''' <summary>
        ''' The atomic element of data for any filesystem object.
        ''' </summary>
        ''' <remarks></remarks>
        Private _fileSystemItem As FileSystemItem

        ''' <summary>
        ''' The set of items that represent the history of changes to an object.
        ''' </summary>
        ''' <remarks></remarks>
        Private _fileSystemItemHistory As FileSystemItemSet

        ''' <summary>
        ''' The name of the filesystem this object was obtained from.
        ''' </summary>
        ''' <remarks></remarks>
        Private _fileSystemName As String

        Private _id As Integer

        ''' <summary>
        ''' The parent object for this instance.
        ''' </summary>
        ''' <remarks>If this object is mounted under another directory,
        ''' this value will point to the new parent directory.</remarks>
        Private _parentEntity As FileSystemEntity

        Private _viewDate As Date?


#Region " Constructors "
        ''' <summary>
        ''' Initializes a new instance of a <see cref="FileSystemEntity"/>.
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub New()
        End Sub

        ''' <summary>
        ''' Initializes a new instance of a <see cref="FileSystemEntity"/> using
        ''' the specified <paramref name="path"/>.
        ''' </summary>
        ''' <param name="path"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal path As String)
            ' the dbfs instance to connect to is given by the high level
            ' qualifier in the path using the UNC convention
            If path.StartsWith(UNC_CHARS) Then
                Dim i As Int16 = path.IndexOfAny(DIRECTORY_SEP_CHARS, 2)
                If i = -1 Then
                    Throw New ArgumentException("Invalid path")
                End If
                _fileSystemName = path.Substring(2, i - 2)
            End If
        End Sub
#End Region ' Constructors

#Region " Fields "
        ''' <summary>
        ''' The root entity of this entity
        ''' </summary>
        ''' <remarks></remarks>
        Public Root As DirectoryEntity
#End Region ' Fields

#Region " Operators "
        Public Shared Operator =(ByVal a As FileSystemEntity, ByVal b As FileSystemEntity) As Boolean
            Return (a Is b)
        End Operator

        Public Shared Operator <>(ByVal a As FileSystemEntity, ByVal b As FileSystemEntity) As Boolean
            Return (a IsNot b)
        End Operator
#End Region ' Operators

#Region " Properties "
        ''' <summary>
        ''' Gets the access rights for the <i>current</i> user.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>The <i>AccessRights</i> as calculated for the current user by <see cref="FileSystemSecurity"/>
        ''' are cached locally.</remarks>
        Public Overridable ReadOnly Property AccessRights() As System.Security.AccessControl.FileSystemRights
            Get
                If _accessRights = 0 Then
                    _accessRights = FileSystemSecurity.AccessRights
                End If
                Debug.WriteLine("AccessRights: --> Name=" & Name & ", _accessRights=" & _accessRights & _
                                " (" & _accessRights.ToString & ")")
                Return _accessRights
            End Get
        End Property

        ''' <summary>
        ''' Gets or sets the attributes for the current file or directory.
        ''' </summary>
        ''' <value><see cref="FileAttributes"/> of the current <see cref="FileSystemInfo"/>.</value>
        ''' <returns></returns>
        ''' <remarks>The value of this property is a combination of the archive, compressed, 
        ''' directory, hidden, offline, read-only, system, and temporary file attribute flags.</remarks>
        Public Overridable Property Attributes() As FileAttributes
            Get
                Return _fileSystemItem.Attributes
            End Get
            Set(ByVal value As FileAttributes)
                _fileSystemItem.Attributes = value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets a Date that represents the cancel date of the object.
        ''' The cancel date of the object is the last date the object is available,
        ''' including up through midnight of that date.
        ''' </summary>
        ''' <value>A Date that represents the cancel date of the object.</value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overridable Property CancelDateUtc() As Date? 'Implements IDbfsNodeItem.CancelDate
            Get
                Return _fileSystemItem.CancelDateUtc
            End Get
            Set(ByVal value As Date?)
                _fileSystemItem.CancelDateUtc = value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the time, in coordinated universal time (UTC), when the 
        ''' current file or directory was created.
        ''' </summary>
        ''' <value>The UTC time when the current file was created.</value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overridable Property CreationTimeUtc() As DateTime
            Get
                Return _fileSystemItem.CreationTimeUtc
            End Get
            Set(ByVal value As Date)
                _fileSystemItem.CreationTimeUtc = value
            End Set
        End Property

        ''' <summary>
        ''' Gets the date/time that represents the time when this record became invalid.
        ''' </summary>
        ''' <value>A Date indicating when this record was effectively deleted.</value>
        ''' <returns></returns>
        ''' <remarks>The Delete time will only be populated if object changes are being tracked.</remarks>
        Public Overridable ReadOnly Property DeleteTimeUtc() As Date?
            Get
                Return _fileSystemItem.DeleteTimeUtc
            End Get
        End Property

        ''' <summary>
        ''' Gets or sets a Date that represents the effective date of the object.
        ''' The effective date of the object is the date when it is first available.
        ''' </summary>
        ''' <value>A Date that represents the effective date of the object.</value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overridable Property EffectiveDateUtc() As DateTime
            Get
                Return _fileSystemItem.EffectiveDateUtc
            End Get
            Set(ByVal value As Date)
                _fileSystemItem.EffectiveDateUtc = value.Date
            End Set
        End Property

        Public Overridable ReadOnly Property EffectivePath() As String
            Get
                Dim nodePath As String = Name
                Dim firstChar As Char = nodePath.Substring(0, 1)
                If Not (firstChar = DIRECTORY_SEP_CHAR OrElse firstChar = ALT_DIRECTORY_SEP_CHAR) Then
                    nodePath = DIRECTORY_SEP_CHAR & nodePath
                End If
                If _parentEntity Is Nothing Then
                    Return nodePath
                Else
                    Dim parentEffectivePath As String = _parentEntity.EffectivePath
                    If parentEffectivePath = DIRECTORY_SEP_CHAR OrElse parentEffectivePath = ALT_DIRECTORY_SEP_CHAR Then
                        Return nodePath
                    End If
                    Return parentEffectivePath & nodePath
                End If
            End Get
        End Property

        ''' <summary>
        ''' Gets or sets the dictionary of extended attributes.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overridable Property ExtendedAttributes() As NodeAttributes
            Get
                If _extendedAttributes Is Nothing Then _
                    _extendedAttributes = New NodeAttributes
                Return _extendedAttributes
            End Get
            Set(ByVal value As NodeAttributes)
                _extendedAttributes = value
            End Set
        End Property

        ''' <summary>
        ''' Refers to the current FileSystemItem based on the selected
        ''' view date of the filesystem.  FileSystemItem is a reference to
        ''' an entry in a FileSystemItemSet.
        ''' </summary>
        ''' <remarks></remarks>
        Public Overridable Property FileSystemItem() As FileSystemItem
            Get
                Return _fileSystemItem
            End Get
            Set(ByVal value As FileSystemItem)
                _fileSystemItem = value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the set of items that represent the layers of history 
        ''' for a given node in the filesystem.
        ''' </summary>
        ''' <remarks></remarks>
        Public Overridable Property FileSystemItemHistory() As FileSystemItemSet
            Get
                Return _fileSystemItemHistory
            End Get
            Set(ByVal value As FileSystemItemSet)
                _fileSystemItemHistory = value
            End Set
        End Property

        ''' <summary>
        ''' Returns the name of the file system in which this entity exists.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property FileSystemName() As String
            Get
                Return _fileSystemName
            End Get
        End Property

        ''' <summary>
        ''' Gets the <see cref="FileSystemSecurity"/> object the encapsulates the
        ''' access control list (ACL) entries for the object described by the current
        ''' <see cref="FileSystemItem"/> object.
        ''' </summary>
        ''' <value>A <see cref="FileSystemSecurity"/> object that encapsulates the 
        ''' access control rules for the filesystem item.</value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public ReadOnly Property FileSystemSecurity() As Security.FileSystemSecurity
            Get
                If FileSystemItem.FileSystemSecurity Is Nothing Then
                    FileSystemItem.FileSystemSecurity = New DbfsDirectorySecurity()
                End If
                Return FileSystemItem.FileSystemSecurity
            End Get
        End Property

        ''' <summary>
        ''' Gets the full path of the directory or file.
        ''' </summary>
        ''' <value>A string containing the full path.</value>
        ''' <returns></returns>
        ''' <remarks>For example, for a file \NewFile.txt, this property
        ''' returns "\NewFile.txt".</remarks>
        Public Overridable ReadOnly Property FullName() As String
            Get
                Return FileSystemItem.FullPath
            End Get
        End Property

        ''' <summary>
        ''' Gets or sets the <see cref="FileSystemItemSet"/> containing the set
        ''' of <see cref="FileSystemItem"/> representing the history of this node.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overridable Property History() As FileSystemItemSet
            Get
                Return _fileSystemItemHistory
            End Get
            Set(ByVal value As FileSystemItemSet)
                _fileSystemItemHistory = value
            End Set
        End Property

        ''' <summary>
        ''' Gets the unique ID associated with this object.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overridable ReadOnly Property Id() As Integer
            Get
                Return _id
            End Get
        End Property

        ''' <summary>
        ''' Gets or sets the time, in coordinated universal time (UTC), that the current file 
        ''' or directory was last accessed.
        ''' </summary>
        ''' <value>The UTC time that the current file or directory was last accessed.</value>
        ''' <returns></returns>
        ''' <remarks>If the file described in the FileSystemInfo object does not
        ''' exist, this property will return 12:00 midnight, January 1, 1601 A.D.
        ''' (C.E.) Coordinated Universal Time (UTC), adjusted to local time.</remarks>
        Public Overridable Property LastAccessTimeUtc() As DateTime
            Get
                Return _fileSystemItem.LastAccessTimeUtc
            End Get
            Set(ByVal value As DateTime)
                _fileSystemItem.LastAccessTimeUtc = value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets the time, in coordinated universal time (UTC), when the 
        ''' current file or directory was last written to.
        ''' </summary>
        ''' <value>The UTC time when the current file was last written to.</value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Overridable Property LastWriteTimeUtc() As DateTime
            Get
                Return _fileSystemItem.LastWriteTimeUtc
            End Get
            Set(ByVal value As DateTime)
                _fileSystemItem.LastWriteTimeUtc = value
            End Set
        End Property

        ''' <summary>
        ''' For files, gets the name of the file. For directories, gets the name of the 
        ''' last directory in the hierarchy if a hierarchy exists. Otherwise, the Name 
        ''' property gets the name of the directory.
        ''' </summary>
        ''' <value>A string that is the name of the parent directory, the name of the 
        ''' last directory in the hierarchy, or the name of a file, including the file 
        ''' name extension.</value>
        ''' <returns></returns>
        ''' <remarks>For a directory, Name returns only the name of the parent directory, 
        ''' such as Dir, not c:\Dir. For a subdirectory, Name returns only the name of the 
        ''' subdirectory, such as Sub1, not c:\Dir\Sub1. <para/>For a file, Name returns 
        ''' only the file name and file name extension, such as MyFile.txt, 
        ''' not c:\Dir\Myfile.txt</remarks>
        Public Overridable Property Name() As String
            Get
                Return _fileSystemItem.Name.Value
            End Get
            Set(ByVal value As String)
                _fileSystemItem.Name.Value = value
            End Set
        End Property

        ''' <summary>
        ''' Gets or sets an instance of an <i>entity</i> the refers to the parent node
        ''' of this node in the filesystem.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks>This value is instance specific.</remarks>
        Public Overridable Property ParentEntity() As FileSystemEntity
            Get
                Return _parentEntity
            End Get
            Set(ByVal value As FileSystemEntity)
                _parentEntity = value
            End Set
        End Property

        ''' <summary>
        ''' For files, gets the name of the file. For directories, gets the name of the 
        ''' last directory in the hierarchy if a hierarchy exists. Otherwise, the Name 
        ''' property gets the name of the directory.
        ''' </summary>
        ''' <value>A string that is the name of the parent directory, the name of the 
        ''' last directory in the hierarchy, or the name of a file, including the file 
        ''' name extension.</value>
        ''' <returns></returns>
        ''' <remarks>For a directory, Name returns only the name of the parent directory, 
        ''' such as Dir, not c:\Dir. For a subdirectory, Name returns only the name of the 
        ''' subdirectory, such as Sub1, not c:\Dir\Sub1. <para/>For a file, Name returns 
        ''' only the file name and file name extension, such as MyFile.txt, 
        ''' not c:\Dir\Myfile.txt</remarks>
        Public Overridable ReadOnly Property ShortName() As String
            Get
                Return _fileSystemItem.Name.ShortName
            End Get
        End Property

        ''' <summary>
        ''' Gets or sets the Track-changes flag for this folder.
        ''' </summary>
        ''' <value>A Boolean value indicating if changes to this folder are tracked.</value>
        ''' <returns></returns>
        ''' <remarks>Transactions should always be used when <b>TrackChanges</b> is enabled
        ''' to reduce the number of records written to the database.</remarks>
        Public Overridable Property TrackChanges() As Boolean
            Get
                Return _fileSystemItem.TrackChanges
            End Get
            Set(ByVal value As Boolean)
                _fileSystemItem.TrackChanges = value
            End Set
        End Property

        Public Overridable Property ViewDate() As Date?
            Get
                Return _viewDate
            End Get
            Set(ByVal value As Date?)
                _viewDate = value
                'FileSystemItem = History(value)
            End Set
        End Property
#End Region ' Properties

#Region " Methods "
        ''' <summary>
        ''' Clears the cached access rights of the current user.
        ''' </summary>
        ''' <remarks>Occurs when access rights are updated.</remarks>
        Public Sub ClearAccessRights()
            _accessRights = 0
        End Sub

        Public Function Clone() As FileSystemEntity
            Return MemberwiseClone()
        End Function

        Public Overridable Sub Refresh()
        End Sub
#End Region ' Methods

    End Class

End Namespace


